package xyz.imeans.w.util;

import java.util.Random;

public class LngLatUtil {
    private LngLatUtil(){}

    // 地球半径，单位为公里
    private static final double EARTH_RADIUS = 6371.0;

    /**
     * 随机生成坐标点
     * @param centralLat 中心点纬度
     * @param centralLon 中心点经度
     * @param radiusKm 半径，单位为公里
     * @return
     */
    public static String create(double centralLat, double centralLon, double radiusKm) {
        Random random = new Random();
        double newLat, newLon;
        double deltaLat, deltaLon;

        do {
            // 随机生成点与中心点的纬度差（弧度）
            deltaLat = radiusKm * (random.nextDouble() * 2 * Math.PI / 360);
            // 随机生成点与中心点的经度差（弧度），考虑纬度对经度的影响
            deltaLon = radiusKm * (random.nextDouble() * 2 * Math.PI / 360) / Math.cos(Math.toRadians(centralLat));

            // 计算新点的纬度和经度
            newLat = centralLat + deltaLat;
            newLon = centralLon + deltaLon;

            // 将新点的纬度限制在[-90, 90]度范围内
            newLat = Math.max(-90, Math.min(90, newLat));
        } while (haversineDistance(centralLat, centralLon, newLat, newLon) > radiusKm);

        // 返回新的坐标点
        return String.format("[%s,%s]", newLon, newLat);
    }

    // Haversine公式计算两点间的距离（单位：公里）
    private static double haversineDistance(double lat1, double lon1, double lat2, double lon2) {
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);
        lat1 = Math.toRadians(lat1);
        lat2 = Math.toRadians(lat2);

        double a = Math.pow(Math.sin(dLat / 2), 2) +
                Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return EARTH_RADIUS * c;
    }

}
